#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <mosquitto.h>
#include "auth.h"





#define HOST "127.0.0.1"
#define PORT 8883

#define PUB_QOS 1
#define SUB_QOS 1

#define MESSAGE_COUNT 100000L
#define MESSAGE_SIZE 1024L

static bool run = true;
static int message_count = 0;
static struct timeval start, stop;
//FILE *fptr = NULL;
extern struct server_config_t config;


void sub_connect_callback(struct mosquitto *mosq, void *obj, int rc) {
    printf("coad sub connected!\n");
    ///printf("rc: %d\n", rc);
}

void sub_disconnect_callback(struct mosquitto *mosq, void *obj, int result) {
    printf("coad sub disconnected!\n");
    run = false;
}

void sub_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg) {
    if (message_count == 0) {
        gettimeofday(&start, NULL);
    }
    //fwrite(msg->payload, sizeof(uint8_t), msg->payloadlen, fptr);
    message_count++;
    if (message_count == MESSAGE_COUNT) {
        gettimeofday(&stop, NULL);
        mosquitto_disconnect((struct mosquitto *) obj);
    }
    printf("++++++%d\n", ((struct coa_rep*) msg->payload)->coa_flag);
}





void my_connect_callback(struct mosquitto *mosq, void *obj, int rc) {
    printf("connected!\n");
    ///printf("rc: %d\n", rc);
}

void my_disconnect_callback(struct mosquitto *mosq, void *obj, int result) {
    printf("disconnected!\n");
    run = false;
}

void my_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg) {
    struct coa_rep coa_msg;
    return;
    if (message_count == 0) {
        gettimeofday(&start, NULL);
    }
    //fwrite(msg->payload, sizeof(uint8_t), msg->payloadlen, fptr);
    message_count++;
    if (message_count == MESSAGE_COUNT) {
        gettimeofday(&stop, NULL);
        mosquitto_disconnect((struct mosquitto *) obj);
    }
    memset(&coa_msg,0,sizeof(struct coa_rep));
    memcpy(&coa_msg,msg->payload,sizeof(struct coa_rep));
    if(coa_msg.coa_flag==1){
        radcliCOAACKRep(G_auth.radDM, &coa_msg.msg, &coa_msg.msg.from);
    }else{
        radcliCOANAKRep(G_auth.radDM, &coa_msg.msg, &coa_msg.msg.from);
    }
    // printf("%s\n", (char*) msg->payload);
}



int pub_coa_msg(const char *topic, int payloadlen, const void *payload,int coa_flag){
struct mosquitto *mosq;
struct coa_rep  coa_msg;


  // double dstart, dstop, diff;
    int mid = 0;
    char id[50];

    memset(&coa_msg,0,sizeof(struct coa_rep));
    coa_msg.coa_flag = htonl(coa_flag);
    
    memcpy(&coa_msg.msg,payload,payloadlen);
    DEBUG("flag=%d  len=%d off=%d  topic=%s",coa_msg.coa_flag,coa_msg.msg.len,coa_msg.msg.off,topic);
    snprintf(id, 50, "msgps_sub_%d", getpid());
    mosq = mosquitto_new(id, true, NULL);
    mosquitto_connect_callback_set(mosq, my_connect_callback);
    mosquitto_disconnect_callback_set(mosq, my_disconnect_callback);
    mosquitto_message_callback_set(mosq, my_message_callback);
    
    mosquitto_username_pw_set(mosq,"admin","admin");
    
    mosquitto_connect(mosq, HOST, PORT, 600);
    //mosquitto_subscribe(mosq, &mid, "/ap/550e8400-e29b-41d4-a716-446655440000", PUB_QOS);
    coa_msg.msg.len=htonl(coa_msg.msg.len);
    coa_msg.msg.off=htonl(coa_msg.msg.off);
   // coa_msg.coa_flag=htonl(coa_msg.coa_flag);
    mosquitto_publish(mosq,&mid,topic,payloadlen+sizeof(int),(void*)(&coa_msg),PUB_QOS,false);
    mosquitto_destroy(mosq);
    mosquitto_lib_cleanup();
   

    
}
        

void* coa_msg(void* arg) {
    struct mosquitto *mosq;

    int mid = 0;
    char id[50];

    start.tv_sec = 0;
    start.tv_usec = 0;
    stop.tv_sec = 0;
    stop.tv_usec = 0;

    mosquitto_lib_init();

    snprintf(id, 50, "msgps_sub_%d", getpid());
    mosq = mosquitto_new(id, true, NULL);
    mosquitto_connect_callback_set(mosq, sub_connect_callback);
    mosquitto_disconnect_callback_set(mosq, sub_disconnect_callback);
    mosquitto_message_callback_set(mosq, sub_message_callback);

    mosquitto_username_pw_set(mosq, config.mqtt_username, config.mqtt_passwd);

    mosquitto_connect(mosq, config.server, config.mqtt_port, 600);
    mosquitto_subscribe(mosq, &mid, "coa_server", SUB_QOS);

    mosquitto_loop_forever(mosq, 10, 1);

    mosquitto_destroy(mosq);
    mosquitto_lib_cleanup();

    printf("++++++++++++++++++++++++\n");
    return 0;
}
